package com.wallace.downloadserver.interceptor

import com.wallace.downloadserver.annotation.VerifyToken
import com.wallace.downloadserver.myconst.DefineName
import com.wallace.downloadserver.myconst.ResponseMessage
import com.wallace.downloadserver.redis.RedisManager
import com.wallace.downloadserver.util.myToken.TokenContent
import org.slf4j.Logger
import org.slf4j.LoggerFactory
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.data.redis.core.RedisTemplate
import org.springframework.stereotype.Component
import org.springframework.web.method.HandlerMethod
import org.springframework.web.servlet.HandlerInterceptor
import javax.servlet.http.HttpServletRequest
import javax.servlet.http.HttpServletResponse

/**
 * @Author: Wallace
 * @Description:
 * 判断请求是否携带token，若携带则解析token
 * 然后判断所请求的方法是否带有@VerifyToken注解
 * 有则需判断该token是否有权限请求该接口
 * @Date: 2022/1/20 1:06
 * @Modified By:
 */
@Component
class TokenInterceptor : HandlerInterceptor {

    private val log: Logger = LoggerFactory.getLogger(TokenInterceptor::class.java)

    private var redisTokenDB: RedisTemplate<String, Any>? = null

    @Autowired
    private fun setRedisTokenDB(redisManager: RedisManager) {
        redisTokenDB = redisManager.getTokenDB()
    }

    override fun preHandle(httpRequest: HttpServletRequest, httpResponse: HttpServletResponse, handler: Any): Boolean {
        if (handler.javaClass.isAssignableFrom(HandlerMethod::class.java)) {
            val handlerMethod = handler as HandlerMethod
            // 是否有@VerifyToken注解
            if (handlerMethod.getMethodAnnotation(VerifyToken::class.java) != null) {
                val tokenContent = httpRequest.getAttribute(DefineName.TOKEN_CONTENT) as? TokenContent
                if (tokenContent == null) {
                    httpResponse.sendError(HttpServletResponse.SC_FORBIDDEN, ResponseMessage.Error.NO_TOKEN)
                    return false
                } else {
                    // 所调的接口
                    val interfaceName = httpRequest.requestURI
                    // 验证该token是否使用该接口
                    if (!tokenContent.interfaces.contains(interfaceName)) {
                        // 获取token
                        val token = httpRequest.getHeader(DefineName.TOKEN)
                        log.warn("无权限调用:{token = $token,interfaceName = $interfaceName}")
                        httpResponse.sendError(HttpServletResponse.SC_FORBIDDEN, ResponseMessage.Error.NO_PERMISSION)
                        return false
                    }
                }
            }
        }
        return true
    }
}